import unittest
import tempfile
import shutil
import os
import json
from datetime import datetime, timedelta

from black_list import Blacklist


class TestBlacklist(unittest.TestCase):
    def setUp(self):
        self.temp_dir = os.path.dirname(__file__)
        self.file_name = 'blacklist.json'
        self.file_path = os.path.dirname(__file__)
        self.full_path = os.path.join(self.file_path, self.file_name)
        print(self.full_path)

        self.test_items = [
            {'item': 'a', 'add_time': (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')},
            {'item': 'b', 'add_time': (datetime.now() + timedelta(minutes=10)).strftime('%Y-%m-%d %H:%M:%S')},
        ]

        if not os.path.exists(self.file_path):
            os.makedirs(self.file_path, exist_ok=True)

        with open(self.full_path, 'w', encoding='utf-8') as f:
            json.dump(self.test_items, f, ensure_ascii=False, indent=2)

    # def tearDown(self):
        # shutil.rmtree(self.temp_dir)

    def test_load_blacklist(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        self.assertEqual(len(bl.blacklist), 1)
        self.assertEqual(len(bl.whitelist), 1)

    def test_is_blocked(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        self.assertTrue(bl.is_blocked('b'))
        self.assertFalse(bl.is_blocked('a'))

    def test_get_unblocked_items(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        items = bl.get_unblocked_items(['a', 'b', 'c'])
        self.assertIn('a', items)
        self.assertIn('c', items)
        self.assertNotIn('b', items)

    def test_block_unblock_item(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        bl.block_item('x')
        self.assertTrue(bl.is_blocked('x'))
        bl.unblock_item('x')
        self.assertFalse(bl.is_blocked('x'))

    def test_block_unblock_items_batch(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        bl.block_items(['m', 'n'])
        self.assertTrue(bl.is_blocked('m'))
        self.assertTrue(bl.is_blocked('n'))
        bl.unblock_items(['m', 'n'])
        self.assertFalse(bl.is_blocked('m'))
        self.assertFalse(bl.is_blocked('n'))

    def test_save_and_reload(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        bl.block_item('z')
        bl.save()
        # Force reload
        Blacklist._instance_pool = {}
        bl2 = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        self.assertTrue(bl2.is_blocked('z'))

    def test_get_next_unblocked_item(self):
        bl = Blacklist.load_blacklist(file_name=self.file_name, file_path=self.file_path, block_time='30m')
        pool = ['a', 'b', 'c']

        next_item = bl.get_next_unblocked_item(pool, strategy='linear')
        self.assertEqual(next_item, 'a')

        next_item = bl.get_next_unblocked_item(pool, strategy='random')
        self.assertIn(next_item, ['a', 'c'])

        next_item = bl.get_next_unblocked_item(pool, strategy='next')
        self.assertEqual(next_item, 'a')
        next_item = bl.get_next_unblocked_item(pool, strategy='next')
        self.assertEqual(next_item, 'c')
        next_item = bl.get_next_unblocked_item(pool, strategy='next')
        self.assertIsNone(next_item)

        # Reset and test round
        # delattr(bl, '_last_index')
        next_item = bl.get_next_unblocked_item(pool, strategy='round')
        self.assertEqual(next_item, 'a')
        next_item = bl.get_next_unblocked_item(pool, strategy='round')
        self.assertEqual(next_item, 'c')
        next_item = bl.get_next_unblocked_item(pool, strategy='round')
        self.assertEqual(next_item, 'a')

if __name__ == '__main__':
    unittest.main()